#include "base.h"
#include "debug.h"
#include "ktty.h"

#include "string.h"


#define colume_max		80
#define line_max		25

#define bytes_per_line	160

#define TTY_BASE		0x0B8000

struct tty	ktty;


int init_ktty(void){
	int i;
	int base = TTY_BASE;
	
	for ( i = 0; i < line_max; i ++, base += bytes_per_line){
		ktty.line[i] = (char *)base;
		ktty.line_len[i] = 0;
		ktty.pos_x = 0;
		ktty.pos_y = 3;
	}
	return 0;
}

int vga_addr(void){
	int memory = (ktty.pos_y * bytes_per_line + ktty.pos_x * 2) + TTY_BASE;
	__asm__("movl %0,%%edi;		\n\t"
		:
		:"m"(memory));
	return 0;
}

int next_line(void){
	ktty.pos_x = 0;
	ktty.pos_y  ++;
	
	return 0;
}

int back_line(void){
	ktty.pos_x = 0;
	ktty.pos_y --;
	
	return 0;
}

BOOL is_out_line(void){
	if (ktty.pos_y == line_max){
		ktty.pos_y --;
		return TRUE;
	}
	
	return FALSE;
}

int line_head(void){
	ktty.pos_x = 0;
	
	return 0;
}

int line_tail(void){
	//cur_pos_x = 0;
	
	return 0;
}
	
int next_cursor(void){
	ktty.pos_x ++;

	return 0;
}

int do_scroll(void){
	/* scroll one line one time */
	int i;		/* line index */
#if 0
	int j;		/* per byte to move */
	int from;
	int to;
#endif

	for (i = 1; i <= ktty.pos_y; i++){
		memcpy(ktty.line[i - 1],ktty.line[i],bytes_per_line);
	}
#if 0
	for ( i = 1; i < ktty.pos_y; i++){
		for ( j = 0 ; j < bytes_per_line; j++){
			from = i * 160 + j;			/* from address */
			to = (i - 1) * 160 + j;		/* to address */
			__asm__("movb %%gs:(%0), %%bl;		\n\t"
			"movb %%bl,%%gs:(%1);				\n\t"
			:
			:"a"(from),"d"( to));
		}
	}
#endif
	return 0;
}	

int clear_current_line(void){
	memset(ktty.line[ktty.pos_y],0x00,bytes_per_line);
#if 0
	char line_null[81] = { [0 ... 79] = ' ',0};
	
	kputs(line_null);
	back_line();
#endif
	return 0;
}

int scroll(void){
	do_scroll();
	clear_current_line();
	return 0;
}

static BOOL is_newline_char(char *str_p){
	if ((*str_p == 0x0A)  || (*str_p == 0x0D)){
		return TRUE;
	}

	return FALSE;
}


int kputs(char *str){
	if (str == NULL){
		return 0;
	}
	
	while(*str){
		if (is_newline_char(str)){
			next_line();
			
			if (is_out_line()){
				scroll();
			}
		}else{
			kputc(*str);
			next_cursor();
			if (ktty.pos_x == colume_max){
				next_line();
				if (is_out_line()){
					scroll();
				}
			}
		}
		
		str ++;
	}
	
	return 0;
}

/* EOF */

